using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using BEPUphysics.Entities;
using MagicArenaXNA.World;
using BEPUphysics.Entities.Prefabs;
using BEPUphysics.EntityStateManagement;
using BEPUphysicsDemos.AlternateMovement.SimpleCharacter;
using BEPUphysics.CollisionShapes;
using BEPUphysics.DataStructures;
using MagicArenaXNA.Games;
using BEPUphysicsDrawer.Models;
using BEPUphysicsDemos;
using MagicArenaXNA.Assets;
using MagicArenaXNA.ControllerInput;
using Networking;
using MagicArenaFramework.GameObject.Components;
using MagicArenaFramework.GameObject.Components.ConcreteTypes;
using BEPUphysics;
using MagicArenaFramework.Bepu;
using MagicArenaFramework.GameObject.Attributes;
using MagicArenaFramework.GameObject.Attributes.Concrete;

namespace MagicArenaXNA.GameObject
{
    /// <summary>
    /// This is a game component that implements IUpdateable.
    /// </summary>
    public class PlayerRemote
    {
        public float Height = 2, Width=0.5f, SupportHeight=0, Mass=75 ;
        public SimpleCharacterController Controller {get;private set;}
        public Entity Body { get; private set; }
        public Model Model { get; private set; }
        public SimpleGameClient Client { get { return Remote.Client; } }
        public UInt64 PlayerId { get { return Remote.PlayerId; } }
        RemoteEntityController Remote { get; set; }


        public DisplayEntityModel meshShape;
        

        public PlayerRemote(BepuGame game, BepuWorld world, Vector3 position, SimpleGameClient client, UInt64 playerId)
        {
            

            Body = new Capsule(position, 2 - 0.8f, 0.8f / 2);
            Body.BecomeKinematic();
            Body.Position = position;
            world.Space.Add(Body);

            // Create model of character
            
            Model = TestAssetHolder.Instance.Crono;
            
            meshShape = new DisplayEntityModel(Body, Model, game.ModelDrawer);

            Remote = new RemoteEntityController(client, Body, playerId);
        }

        public void Activate()
        {
            
            meshShape.ModelDrawer.Add(meshShape);
        }

        public void Update(float dt)
        {
            Remote.Update(dt);
        }

    }

    public class PlayerRemoteComp : GoComposite
    {
        public float Height = 2, Width = 0.5f, SupportHeight = 0, Mass = 75;
        public UInt64 PlayerId { get; private set; }
        

        public PlayerRemoteComp(BepuGame game, BepuWorld world, Vector3 position, SimpleGameClient client, UInt64 playerId)
        {
            PlayerId = playerId;

            Entity Body = AddEntity(position, world.Space);

            // Create model of character and renderer
            AddRenderer(Body, game.ModelDrawer);

            //Create remote connection
            AddController(Body, playerId, client);

            AddAtttributes();
        }

        #region Add components
        Entity AddEntity(Vector3 position, Space space)
        {
            Entity Body = new Capsule(position, 2 - 0.8f, 0.8f / 2);
            Body.Position = position;
            CustomTag tag = new CustomTag();
            tag.TagProp.Add("name", "PlayerRemoteBody");
            tag.IsTargettable = true;
            tag.IsBepuDisplayable=true;
            tag.IsDamagable = true;
            tag.Component = this;
            tag.Entity = Body;
            Body.Tag = tag;
            EntityComponent EntComp = new EntityComponent(Body, space);
            AddChild(EntComp);
            return Body;
        }
        void AddRenderer(Entity body, ModelDrawer drawer)
        {
            Model Model = TestAssetHolder.Instance.Crono;
            EntityModelRender rend = new EntityModelRender(body, Model, drawer);
            AddChild(rend);
        }
        void AddController(Entity body, UInt64 playerId, SimpleGameClient client)
        {
            ControllerRemote remote = new ControllerRemote(body, playerId, client);
            AddChild(remote);
        }
        void AddAtttributes()
        {
            ScalarAttributeHolder att = new ScalarAttributeHolder();
            att.AddChild(new MaxHealthAttribute(1000));
            att.AddChild(new CurHealthAttribute(1000, 500));
            att.AddChild(new RegenHealthAttribute(15));
            att.AddChild(new MaxManaAttribute(500));
            att.AddChild(new CurManaAttribute(500, 250));
            att.AddChild(new RegenManaAttribute(50));
            AddChild(att);
        }
        #endregion
    }
}
